#ifndef GAMEENGINE_GEOMETRY_HEXAGON2D_H
#define GAMEENGINE_GEOMETRY_HEXAGON2D_H

#include <GameEngine/Geometry/geometry_settings.h>

#include <GameEngine/Geometry/Location/point2d.h>
#include <GameEngine/Geometry/Location/vector2d.h>
#include <GameEngine/Geometry/Lines/line2d.h>
#include <GameEngine/Geometry/Core/angle.h>
#include <GameEngine/Geometry/Surfaces/trgl2dfast.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

namespace Hexagon2D {
	//! Point index along a hexagon
	enum Index {
		//! First point
		First = 0,
		//! Second point
		Second = 1,
		//! Third point
		Third = 2,
		//! Fourth point
		Fourth = 3,
		//! Fifth point
		Fifth = 4,
		//! Sixth point
		Sixth = 5
	};
}



//! Class used to represent 2D hexagons
/*!
 @note A 2D hexagon is made of a center and an orientation vector
 @note Most algorithms expect floating point operations. Type T should therefore
       not be an integer type
 */
template <class T>
class Hexagon2d {

public:
	Hexagon2d();
	Hexagon2d(const Point2d<T>& center, const Vector2d<T>& orientation);
	Hexagon2d(const Hexagon2d& rhs);
	virtual ~Hexagon2d();
	Hexagon2d& operator=(const Hexagon2d& rhs);

	Point2d<T>& center();
	const Point2d<T>& center() const;
	Vector2d<T>& orientation();
	const Vector2d<T>& orientation() const;

	Point2d<T> operator[](Hexagon2D::Index index) const;

	bool inside(const Point2d<T>& rhs, bool strict = false) const;
	int intersection(const Line2d<T>& rhs, T& line_coordinate1, T& line_coordinate2, IntersectionType::Type* type = nil) const;
	Point2d<T> closest_point(const Point2d<T>& rhs) const;

	T perimeter() const;
	T area() const;

	bool degenerate(const T& tolerance = 0.000001) const;

protected:
	//! Center of the hexagon
	Point2d<T> center_;

	//! Orientation vector
	Vector2d<T> orientation_;
};

#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/Geometry/Surfaces/hexagon2d.hpp>

#endif
